const crypto = require("crypto");

function md5(data) {
  return crypto.createHash("md5").update(data).digest("hex");
}

function sha1(data) {
  return crypto.createHash("sha1").update(data).digest("hex");
}

// 配置（优先读环境变量）
const APP_ID = process.env.CFMOTO_APP_ID || "azRnLvxl";
const APP_SECRET = process.env.CFMOTO_APP_SECRET || "76d9baa27803da36d07ec4972fd041b32fcec40d";

// 小工具：是否为 FormData（兼容浏览器与 Node form-data）
function isFormDataBody(body) {
  const isBrowserFD = typeof FormData !== "undefined" && body instanceof FormData;
  const isNodeFD = body && typeof body === "object" && typeof body.getBoundary === "function";
  return isBrowserFD || isNodeFD;
}

// 小工具：生成签名所需的 query/data 串
function buildSignPayload(config) {
  const params = { ...(config?.params || {}) };
  const query = Object.keys(params).map((key) => `${key}=${params[key]}`).join("&");
  // 后端固定不使用 queryError
  const queryError = "";

  let data = "";
  if (config?.data && !isFormDataBody(config.data)) {
    try {
      data = JSON.stringify(config.data);
    } catch (_) {
      data = "";
    }
  }
  return { query, queryError, data };
}

/**
 * 生成签名参数
 * @param {Object} config - 请求配置 { params, data }
 * @returns {Object} { timestamp, nonce, sign, appParam, appId }
 */
function generateSignParams(config) {
  const timestamp = Date.now().toString();
  const nonce = Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
  const { query, queryError, data } = buildSignPayload(config);

  const signatureString = `${query}${queryError}${data}appId=${APP_ID}&nonce=${nonce}&timestamp=${timestamp}${APP_SECRET}`;
  const sha1Hash = sha1(signatureString);
  const signatureMd5 = md5(sha1Hash);

  return {
    timestamp,
    nonce,
    sign: signatureMd5,
    appParam: `appId=${APP_ID}&nonce=${nonce}&timestamp=${timestamp}`,
    appId: APP_ID,
  };
}

/**
 * 生成通用签名相关头（不包含 Authorization）
 * @param {{params?: object, data?: any}} config
 * @returns {Record<string,string>}
 */
function addCommonHeaders(config) {
  const { sign, appParam, appId } = generateSignParams(config);
  return {
    "Accept-Language": "zh-CN",
    "Cfmoto-X-Sign": sign,
    "Cfmoto-X-Param": appParam,
    "Cfmoto-X-Sign-Type": "0",
    appid: appId,
    "x-app-info": "MOBILE|Android|9|KLICEN_APP|2.2.5|Dalvik/2.1.0 (Linux; U; Android 9; V2199GA Build/PQ3A.190705.09121602)|720*1280|1|100|wifi|vivo",
  };
}

/**
 * 根据请求与路径构建上游请求头
 * 头部合并优先级（高->低）：
 *  1) 强制头（根据接口类型，如登录强制 Basic）
 *  2) 签名头（Cfmoto-X-* / appid / x-app-info / Accept-Language）
 *  3) 客户端透传的基础头（authorization, accept-language, content-type, user-agent, accept-encoding 等）
 * @param {import('express').Request} req
 * @returns {Record<string, string>}
 */
function buildUpstreamHeaders(req) {
  const path = req.path || req.originalUrl || "";
  const isLogin = /(?:^|[/?])user\/loginByPhone(?:$|[/?])/i.test(path);
  const client = req.headers || {};

  const base = {
    "Accept-Language": client["accept-language"] || "zh-CN",
    "Content-Type": client["content-type"] || "application/json; charset=UTF-8",
    "User-Agent": client["user-agent"] || "okhttp/4.4.0",
    "Accept-Encoding": client["accept-encoding"] || "gzip",
    "x-app-info": client["x-app-info"] || "MOBILE|Android|9|KLICEN_APP|2.2.5|Dalvik/2.1.0 (Linux; U; Android 9; V2199GA Build/PQ3A.190705.09121602)|720*1280|1|100|wifi|vivo",
  };

  const signHeaders = addCommonHeaders({ params: req.query, data: req.body });

  const headers = { ...base, ...signHeaders };

  // Authorization：登录强制 Basic，其余透传
  const auth = client["authorization"];
  if (isLogin) {
    headers["Authorization"] = auth && /^basic\s/i.test(auth) ? auth : "Basic bWNrOjEyMzQ1Ng==";
  } else if (auth) {
    headers["Authorization"] = auth;
  }

  return headers;
}

module.exports = {
  generateSignParams,
  addCommonHeaders,
  buildUpstreamHeaders,
};
